import { Context } from 'koa';
import { AppContext } from '@/types';
import TableConfig from '@/models/TableConfig';
import { validate } from '@/utils/validator';
import * as response from '@/utils/response';
import Joi from 'joi';
import { Op } from 'sequelize';
import sequelize from '@/db';

/**
 * 动态表格配置控制器
 */
export class TableConfigController {
  /**
   * 获取表格配置列表
   */
  async list(ctx: Context) {
    const appCtx = ctx as AppContext;

    const schema = Joi.object({
      page: Joi.number().integer().min(1).default(1),
      pageSize: Joi.number().integer().min(1).max(100).default(10),
      name: Joi.string().max(100),
      code: Joi.string().max(50),
      status: Joi.boolean(),
    });

    interface ListFilter {
      page: number;
      pageSize: number;
      name?: string;
      code?: string;
      status?: boolean;
    }

    const filter = await validate<ListFilter>(ctx.query as any, schema);
    
    const where: any = {};
    
    // 多租户过滤
    if (appCtx.state.tenant) {
      where.tenantId = appCtx.state.tenant.id;
    }
    
    // 搜索条件
    if (filter.name) {
      where.name = { [Op.like]: `%${filter.name}%` };
    }
    
    if (filter.code) {
      where.code = { [Op.like]: `%${filter.code}%` };
    }
    
    if (filter.status !== undefined) {
      where.status = filter.status;
    }

    const offset = (filter.page - 1) * filter.pageSize;
    const { count, rows } = await TableConfig.findAndCountAll({
      where,
      limit: filter.pageSize,
      offset,
      order: [['createdAt', 'DESC']],
    });

    response.paginated(
      ctx,
      rows,
      count,
      filter.page,
      filter.pageSize
    );
  }

  /**
   * 根据code获取表格配置
   */
  async getByCode(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { code } = ctx.params;

    const config = await TableConfig.getConfigByCode(
      code, 
      appCtx.state.tenant?.id
    );

    if (!config) {
      return response.notFound(ctx, '表格配置不存在');
    }

    response.success(ctx, config);
  }

  /**
   * 获取单个表格配置
   */
  async getById(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;

    const where: any = { id };
    
    if (appCtx.state.tenant) {
      where.tenantId = appCtx.state.tenant.id;
    }

    const config = await TableConfig.findOne({ where });

    if (!config) {
      return response.notFound(ctx, '表格配置不存在');
    }

    response.success(ctx, config);
  }

  /**
   * 创建表格配置
   */
  async create(ctx: Context) {
    const appCtx = ctx as AppContext;
    const transaction = await sequelize.transaction();
    
    try {
      const schema = Joi.object({
        code: Joi.string().max(50).required(),
        name: Joi.string().max(100).required(),
        description: Joi.string().max(500),
        tableName: Joi.string().max(100).required(),
        apiPath: Joi.string().max(200),
        fields: Joi.array().items(Joi.object()).required(),
        actions: Joi.object(),
        tableProps: Joi.object(),
        permissions: Joi.object(),
        status: Joi.boolean().default(true),
      });

      interface CreateData {
        code: string;
        name: string;
        description?: string;
        tableName: string;
        apiPath?: string;
        fields: any[];
        actions?: any;
        tableProps?: any;
        permissions?: any;
        status?: boolean;
      }

      const data = await validate<CreateData>(ctx.request.body as any, schema);

      // 检查code是否已存在
      const existingConfig = await TableConfig.findOne({
        where: {
          code: data.code,
          ...(appCtx.state.tenant && { tenantId: appCtx.state.tenant.id }),
        },
      });

      if (existingConfig) {
        await transaction.rollback();
        return response.error(ctx, '配置代码已存在', 400);
      }

      const config = await TableConfig.create(
        {
          ...data,
          status: data.status ?? true,
          tenantId: appCtx.state.tenant?.id,
          createdBy: appCtx.state.user?.id,
          updatedBy: appCtx.state.user?.id,
        },
        { transaction }
      );

      await transaction.commit();

      response.created(ctx, config, '表格配置创建成功');
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  /**
   * 更新表格配置
   */
  async update(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;
    const transaction = await sequelize.transaction();
    
    try {
      const schema = Joi.object({
        code: Joi.string().max(50),
        name: Joi.string().max(100),
        description: Joi.string().max(500),
        tableName: Joi.string().max(100),
        apiPath: Joi.string().max(200),
        fields: Joi.array().items(Joi.object()),
        actions: Joi.object(),
        tableProps: Joi.object(),
        permissions: Joi.object(),
        status: Joi.boolean(),
      });

      interface UpdateData {
        code?: string;
        name?: string;
        description?: string;
        tableName?: string;
        apiPath?: string;
        fields?: any[];
        actions?: any;
        tableProps?: any;
        permissions?: any;
        status?: boolean;
      }

      const data = await validate<UpdateData>(ctx.request.body as any, schema);

      const config = await TableConfig.findOne({
        where: {
          id,
          ...(appCtx.state.tenant && { tenantId: appCtx.state.tenant.id }),
        },
      });

      if (!config) {
        await transaction.rollback();
        return response.notFound(ctx, '表格配置不存在');
      }

      // 如果修改了code，检查新code是否已存在
      if (data.code && data.code !== config.code) {
        const existingConfig = await TableConfig.findOne({
          where: {
            code: data.code,
            id: { [Op.ne]: id },
            ...(appCtx.state.tenant && { tenantId: appCtx.state.tenant.id }),
          },
        });

        if (existingConfig) {
          await transaction.rollback();
          return response.error(ctx, '配置代码已存在', 400);
        }
      }

      await config.update(
        {
          ...data,
          updatedBy: appCtx.state.user?.id,
        },
        { transaction }
      );

      await transaction.commit();

      response.success(ctx, config, '更新成功');
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  /**
   * 删除表格配置
   */
  async delete(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { id } = ctx.params;
    const transaction = await sequelize.transaction();
    
    try {
      const config = await TableConfig.findOne({
        where: {
          id,
          ...(appCtx.state.tenant && { tenantId: appCtx.state.tenant.id }),
        },
      });

      if (!config) {
        await transaction.rollback();
        return response.notFound(ctx, '表格配置不存在');
      }

      await config.destroy({ transaction });
      await transaction.commit();

      response.success(ctx, null, '删除成功');
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }

  /**
   * 批量删除表格配置
   */
  async batchDelete(ctx: Context) {
    const appCtx = ctx as AppContext;
    const transaction = await sequelize.transaction();
    
    try {
      const schema = Joi.object({
        ids: Joi.array().items(Joi.string()).min(1).required(),
      });

      interface BatchDeleteData {
        ids: string[];
      }

      const { ids } = await validate<BatchDeleteData>(ctx.request.body as any, schema);

      const where: any = {
        id: { [Op.in]: ids },
      };

      if (appCtx.state.tenant) {
        where.tenantId = appCtx.state.tenant.id;
      }

      const count = await TableConfig.destroy({
        where,
        transaction,
      });

      await transaction.commit();

      response.success(ctx, { count }, `成功删除 ${count} 条配置`);
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  }
}

export default new TableConfigController();
